

import TranslationEditor from "./TranslationEditor"
import RotationEditor from "./RotationEditor"


export default class Editer {

  constructor(viewer, overlay) {
    this._viewer = viewer
    this._overlay = overlay

    this._active = undefined
    this._modelMatrix = new Cesium.Matrix4()
    this._radius = 100

    this._currentEditor = undefined
    this._callback = (value) => {
      this._overlay.modelMatrix = value
    }

    this._translateEditor = new TranslationEditor({
      scene: this._viewer.scene,
      transform: this._modelMatrix,
      radius: this._radius,
      callback: this._callback
    })

    this._rotationEditor = new RotationEditor({
      scene: this._viewer.scene,
      transform: this._modelMatrix,
      radius: this._radius,
      callback: this._callback
    })
  }

  /**
   * 计算不同的矩阵
   * @returns 
   */
  computedModelMatrix(type) {

    // 为entity情况时 计算模型矩阵
    if (this._overlay.delegate instanceof Cesium.Entity ) {
      return new Promise((resolve, reject) => {

        let position = this._overlay.delegate.position.getValue(Cesium.JulianDate.now())
        let modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame (position , 
          new Cesium.HeadingPitchRoll(
            Cesium.Math.toRadians(this._overlay.heading),
            Cesium.Math.toRadians(this._overlay.pitch),
            Cesium.Math.toRadians(this._overlay.roll)
          )
        )
        let positionModelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
          
        // 旋转从位置创建
        if(type == 'rotation'){
          this._currentEditor.transform = positionModelMatrix
        }else{
          this._currentEditor.transform = modelMatrix
        }
        
        this.callback = (value) => {
          let info = this.getPositionFromMatrix(value)
          this._overlay.positions = info.positions
          this._overlay.heading = info.heading
          this._overlay.pitch = info.pitch
          this._overlay.roll = info.roll
        }
      })
    }

    // 为primitive Model时  从readyPromise返回
    if (this._overlay.delegate instanceof Cesium.Model) {
      return new Promise((resolve, reject) => {
        this._overlay.readyPromise.then(model => {

          if (type == 'rotation') {
            this._currentEditor.transform = this.computedRotateMatrix(model.modelMatrix)
          } else {
            this._currentEditor.transform = model.modelMatrix
          }
          this._modelMatrix = model.modelMatrix
          this._currentEditor.radius = model.boundingSphere.radius

          resolve(model)
        })
      })
    }

    // 为3dtileset时 同样从readyPromise返回
    if (this._overlay.delegate instanceof Cesium.Cesium3DTileset) {
      return new Promise((resolve, reject) => {
        this._overlay.readyPromise.then(tileset => {

          if (type == 'rotation') {
            this._currentEditor.transform = this.computedRotateMatrix(tileset.root.transform)
          } else {
            this._currentEditor.transform = tileset.root.transform
          }

          this._modelMatrix = tileset.root.transform
          this._currentEditor.radius = tileset.boundingSphere.radius
          resolve(tileset)
        })
      })
    }
    
  }

  /**
   * 从模型矩阵计算原始位置
   * @param {*} modelMatrix 
   * @returns 
   */
  computedRotateMatrix(modelMatrix) {
    let x = modelMatrix[12]
    let y = modelMatrix[13]
    let z = modelMatrix[14]
    return Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3(x, y, z))
  }

  /**
   * 计算矩阵原始位置和角度
   * @param {*} modelMatrix 
   * @returns 
   */
  getPositionFromMatrix(modelMatrix) {

    let x = modelMatrix[12]
    let y = modelMatrix[13]
    let z = modelMatrix[14]

    let position = new Cesium.Cartesian3(x, y, z)
    // 计算旋转角度
    let orientation = new Cesium.Quaternion()
    // 计算中心处的变换矩阵
    var m1 = Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Matrix4.getTranslation(modelMatrix, new Cesium.Cartesian3()), Cesium.Ellipsoid.WGS84, new Cesium.Matrix4());
    // 矩阵相相乘
    var m3 = Cesium.Matrix4.multiply(Cesium.Matrix4.inverse(m1, new Cesium.Matrix4()), modelMatrix, new Cesium.Matrix4())
    // 获取3乘3矩阵
    m3 = Cesium.Matrix4.getMatrix3(m3, new Cesium.Matrix3())
    // 获取旋转矩阵
    let rotation = Cesium.Matrix3.getRotation(m3, new Cesium.Matrix3())
    // 从旋转矩阵计算四元数
    orientation = Cesium.Quaternion.fromRotationMatrix(rotation, orientation)
    // 计算角度
    let hpr = Cesium.HeadingPitchRoll.fromQuaternion(orientation)

    let heading = Cesium.Math.toDegrees(hpr.heading)
    let pitch = Cesium.Math.toDegrees(hpr.pitch)
    let roll = Cesium.Math.toDegrees(hpr.roll)
    return {
      positions : position,
      heading,
      pitch,
      roll
    }
  }

  /**
   * 激活编辑工具
   * @param {*} type 
   * @param {*} callback 
   */
  async active(type, callback) {
    this.stop()

    // 平移时模型矩阵正常  
    if (type == 'translate') {
      this._currentEditor = this._translateEditor
    }

    // 旋转时 计算出模型的位置矩阵即可
    if (type == 'rotation') {
      this._currentEditor = this._rotationEditor
    }

    this._currentEditor.active = true
    let model = await this.computedModelMatrix(type)
  }

  
  /**
   * 取消编辑
   */
  deactive(){
    this.stop()
  }

  /**
   * 停止
   */
  stop() {
    this._translateEditor && (this._translateEditor.active = false)
    this._rotationEditor && (this._rotationEditor.active = false)
  }

  /**
   * 
   * @param {*} overlay 
   */
  setOverlay(overlay) {
    this._overlay = overlay
  }

  /**
   * 销毁
   */
  destroy(){
    this._translateEditor && this._translateEditor.destroy()
    this._rotationEditor && this._rotationEditor.destroy()
  }

  get callback() {
    return this._callback
  }

  set callback(val) {
    this._callback = val

    this._currentEditor.callback = val
  }

  get overlay() {
    return this._overlay
  }

  set overlay(overlay) {
    this._overlay = overlay
  }


}